using System;
using System.Linq;
using System.Activities;
using System.ServiceModel;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Workflow;

namespace UpdatePagingLimit
{
    public class UpdateUserPagingLimit : CodeActivity
    {
        [RequiredArgument]
        [Input("Paging Limit Value")]
        public InArgument<int> LimitArgument { get; set; }

        [RequiredArgument]
        [Input("System User")]
        [ReferenceTarget("systemuser")]
        public InArgument<EntityReference> SystemUserArgument { get; set; }

        protected override void Execute(CodeActivityContext executionContext)
        {
            // Create the tracing service
            ITracingService tracingService = executionContext.GetExtension<ITracingService>();

            tracingService.Trace("Entered UpdatePagingLimit.Execute(), Activity Instance Id: {0}, Workflow Instance Id: {1}",
                executionContext.ActivityInstanceId,
                executionContext.WorkflowInstanceId);

            // Create the context
            IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();

            if (context == null)
                throw new InvalidPluginExecutionException("Failed to retrieve workflow context.");

            tracingService.Trace("UpdatePagingLimit.Execute(), Correlation Id: {0}, Initiating User: {1}",
                context.CorrelationId,
                context.InitiatingUserId);

            IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
            IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

            try
            {
                var linqContext = new OrganizationServiceContext(service);
                var limitToSet = LimitArgument.Get<int>(executionContext);
                var userRef = SystemUserArgument.Get<EntityReference>(executionContext);

                if (limitToSet > 500)
                    throw new InvalidPluginExecutionException("Unable to set Paging Limit to " + limitToSet + ", Maximum permitted value is 500.");

                var usersettingsId = (from s in linqContext.CreateQuery("usersettings")
                                      where s.GetAttributeValue<Guid>("systemuserid") == userRef.Id
                                      select s.Id).FirstOrDefault();

                if (usersettingsId != Guid.Empty)
                {
                    var userSettingsToUpdate = new Entity("usersettings") { Id = usersettingsId };
                    userSettingsToUpdate["paginglimit"] = limitToSet;
                    service.Update(userSettingsToUpdate);
                }
                else
                    throw new InvalidPluginExecutionException("Unable to find user settings");

            }
            catch (FaultException<OrganizationServiceFault> e)
            {
                tracingService.Trace("Exception: {0}", e.ToString());
                throw;
            }
            tracingService.Trace("Exiting UpdatePagingLimit.Execute(), Correlation Id: {0}", context.CorrelationId);
        }
    }
}
